import calculator
from thing import *
import random
import races
from action import equip,move

import operator


class Mob(Person):
    def __init__(self):
        Person.__init__(self)
        self.attrs.add("mob")
        self.spawnerUid = None
        self.habitat = []
        self.gil = random.randint(0, 1)
        self.dead = False
        self.stats['encumbrance'] = 5
        self.enemies = []

    def combatTick(self):
        Person.tick(self)
        if self.dead == False:
            if "aggressive" in self.attrs:
                if self.inCombat == False:
                    room = fetch(self.location)
                    if not room: return
                    threatTargs = {}
                    # Parse room for attackable objects
                    for uid in room.contents:
                        thing = fetch(uid)
                        if thing == None: continue
                        if 'person' in thing.attrs:
                            if thing.combatTarget == self.uid:
                                if thing.miscAttrs['hiding'] == False:
                                    self.inCombat = True
                                    self.combatTarget = thing.uid
                                    room.broadcast(self.name+" moves to defend itself!", color.yellow)
                            elif thing.miscAttrs['hiding'] == False:
                                threatTargs.update({thing:thing.stats['threat']})
                    if threatTargs != {}:
                        target = aggroCheck(self, threatTargs)
                        if target == None:pass
                        else:
                            room.broadcast(self.name+" moves to attack "+target.name+"!", color.yellow, target)
                            target.hear(self.name+" moves to attack you!", color.yellow)
                            self.inCombat = True
                            self.combatTarget = target.uid
                            return
                else: #if mob is in combat, keep checking if something builds more threat, then change targets.
                    threatTargs = {}
                    # Parse room for attackable objects
                    room = fetch(self.location)
                    for uid in room.contents:
                        thing = fetch(uid)
                        if thing == None: continue
                        if 'person' in thing.attrs:
                            if thing.miscAttrs['hiding'] == False:
                                threatTargs.update({thing:thing.stats['threat']})
                    if threatTargs != {}:
                        target = aggroCheck(self, threatTargs)
                        if target == None:return
                        if target.uid == self.combatTarget:return
                        else:
                            room.broadcast(self.name+" changes targets to "+target.name+"!", color.yellow, target)
                            target.hear(self.name+" has changed targets, and is now attacking you!", color.yellow)
                            self.combatTarget = target.uid
                    # If mob's target has left the room, attempt pursuit
                    try: # Temporary exception
                        if room.uid != fetch(fetch(self.combatTarget).location).uid: # Compare taget's location and self.location
                            for Exit in room.exits.keys():
                                if room.exits[Exit] == enemyRoom.uid:
                                    motivation = random.randint(1, self.stats['int']+50) # too low, and high level mobs will always chase...
                                    if motivation < self.stats['int']:
                                        from action import move
                                        room.broadcast(self.name+" chases after "+enemy.name+"!", color.yellow)
                                        enemy.hear(self.name+color.red+" is chasing after you!")
                                        move(self, Exit)
                    except: pass
    def combatCheckTick(self):
        room = fetch(self.location)
        if room.contents == 1: return
        for uid in room.contents: # For even better efficiency, merge with actionTick to utilize it's room.contents for-loop
            if uid == self.uid: continue
            person = fetch(uid)
            if person != None and 'person' in person.attrs:
                if person.race == self.race: continue
                if person.race in self.enemies or 'player' in person.attrs:
                    self.combatTick()
                

    def wanderTick(self):
        # Allow the mob to wander the realm
        if not self.inCombat:
            room = fetch(self.location) 
            if room == None: return
            motivation = random.random()*1000
            if motivation < 2.5: # Trying to find a good 'wander' speed. This might be it.
                try:
                    direction = random.choice(room.exits.keys())
                    if fetch(room.exits[direction]).biome in self.habitat:
                        move(self, direction)
                except IndexError: 
                    print "Make a room so mobs can wander!"
                    return

    def actionTick(self):
        # If mob is humanoid, it might pick items up and use them. In progrss
        if 'humanoid' in self.attrs and (not self.inCombat):
            room = fetch(self.location) 
            motivation = int(random.random()*1000)
            if motivation < 2:
                option = random.choice(['gil', 'take', 'equip'])
                if option == 'gil' and room.gil != 0:
                    self.gil += room.gil
                    room.broadcast(self.name+" picks up "+str(room.gil)+".", color.darkgreen)
                    room.gil = 0
                elif option == 'take': # Take an item in the room
                    numnums = []
                    for uid in room.contents:
                        item = fetch(uid)
                        if item != None and 'takeable' in item.attrs:
                            numnums.append(item.uid)
                    if len(numnums) != 0:
                        fetch(random.choice(numnums)).moveInto(self.uid)
                        room.broadcast("A "+self.name+" picks up a "+str(item.name)+".", color.darkgreen)
                        print "A mob just pocketed an item"
                    else: room.broadcast("A "+self.name+" rummages around the room looking for something...", color.darkgreen)
                elif option == 'equip': # wear an item in their inventory
                    numnums = []
                    for uid in self.contents:
                        item = fetch(uid)
                        if item != None and 'equipable' in item.attrs:
                            numnums.append(item)
                    if len(numnums) != 0:
                        equip(self, random.choice(numnums).name)
                        print "A mob just equipped an item"

class Spawner(Thing):
    def __init__(self):
        Thing.__init__(self)
        self.attrs.add("spawner")
        self.name = ""
        self.spawnTimer = 0
        self.mobname = None
        self.mobs = None
        self.minlvl = None
        self.maxlvl = None
        self.timer = None
        self.quantity = None
        self.behaviour = None
    def tick(self):
        room = fetch(self.location)
        self.spawnTimer += 1
        if self.spawnTimer > self.timer*10:
            mobcounter = 0
            for thing in Thing.List:
                if thing == None: continue
                thing = fetch(thing)
                if thing == None:continue
                if 'mob' in thing.attrs:
                    if thing.spawnerUid == self.uid:
                        mobcounter += 1
            if mobcounter < self.quantity:
                mob = Mob()
                mob.name = self.mobname
                mob.level = random.randint(self.minlvl, self.maxlvl)
                mob.race = self.mobs
                mob.spawnerUid = self.uid
                races.raceMaker(mob)
                setAttributes(mob)
                mob.moveInto(room.uid)
                person_stat_updater(mob, True)
                calculator.levelup(mob, mob.stats['con'], mob.stats['int'], True)
                room.broadcast("You notice that a "+mob.race+" has arrived", color.yellow)
                mob.attrs.add("aggressive")
                self.spawnTimer = 0

# This was a horrible idea.... 
"""def enemy(mob, enemy):
    if mob.race == 'vampire':
        if 'player' in enemy.attrs: return True
        if enemy.race == 'werewolf': return True
    if mob.race == 'werewolf':
        if 'player' in enemy.attrs: return True
        if enemy.race == 'vampire': return True
    if mob.race == 'kobold':
        if 'player' in enemy.attrs: return True
        if enemy.race == 'rat': return True
    if mob.race == 'rat':
        if 'player' in enemy.attrs: return True
    if mob.race == 'bat':
        if 'player' in enemy.attrs: return True
    if mob.race == 'orc':
        if 'player' in enemy.attrs: return True
    if mob.race == 'goblin':
        if 'player' in enemy.attrs: return True
    if mob.race == 'spider':
        if 'player' in enemy.attrs: return True
        if enemy.race == "goblin": return True
    else: return False"""

def aggroCheck(self, targets):
    targetOptions = {}
    for person in targets.keys():
        if person.race in self.enemies or 'player' in person.attrs:
            targetOptions[person] = person.stats['threat']
    if targetOptions != {}:
        return max(targetOptions.iteritems(), key=operator.itemgetter(1))[0]

def setAttributes(self):
    """This is where all non-generic mob data is assigned."""
    # Add specific descriptions of each mob here!
    # WEREWOLF
    if self.race == 'werewolf': 
        self.attrs.add("humanoid")
        self.desc = "Raawwwrrr!!!" # <-- Like that!  (but be more creative)
        self.enemies = ['vampire']
        self.habitat = ['swamp', 'forest', 'city']
        self.name = random.choice(['hairy ', 'grizzly ', 'huge ', 'muscular ', '', '', ''])+self.name
    # VAMPIRE
    if self.race == 'vampire':
        self.attrs.add("humanoid")
        self.habitat = ['forest', 'cave']
        self.name = random.choice(['sleek ', 'dark ', 'quick ', 'muscular ','','',''])+self.name
    # ORC
    if self.race == 'orc':
        self.attrs.add("humanoid")
        self.habitat = ['forest', 'swamp', 'plains', 'mountain', 'cave']
        self.name = random.choice(['dirty ', 'hulking ', 'scarred ', 'strong ','','',''])+self.name
    # GOBLIN
    if self.race == 'goblin':
        self.attrs.add("humanoid")
        self.habitat = ['forest', 'cave', 'mountain', 'swamp']
        self.name = random.choice(['wary ', 'slim ', 'small ','','',''])+self.name
    # KOBOLD
    if self.race == 'kobold':
        self.attrs.add("humanoid")
        self.enemies = ['rat']
        self.habitat = ['forest', 'cave', 'mountain']
        self.name = random.choice(['scaly ', 'small ','','',''])+self.name
    # RAT
    if self.race == 'rat':
        self.habitat = ['city', 'forest', 'cave', 'swamp', 'plains']
        self.name = random.choice(['fury ','fury ' 'small ', 'tail-less ','','',''])+self.name
    # SPIDER
    if self.race == 'spider':
        self.enemies = ['kobold']
        self.habitat = ['forest', 'cave', 'swamp']
        self.name = random.choice(['hairy ', 'large ','','',''])+self.name
    # BAT
    if self.race == 'bat':
        self.habitat = ['cave']
        self.name = random.choice(['creepy ', 'small ', 'vampire ','','',''])+self.name


    # TEST
    if self.race == 'test':
        self.attrs.discard("aggressive")
